#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)

#define M 16
#define N 16

int fivechess_broad(char chess[M][N], int L) //构建五子棋盘
{
    int i = 0, j = 0; L = N;
    for (i = 0; i < L; i++) {
        for (j = 0; j < L; j++) {
            chess[i][j] = '+';  //每个位置初始化为“+”
        }
    }
}


int line(int L) {   //绘制分割线
    int i = 0;
    for (i = 1; i < L; i++) {
        printf("——");
    }
    printf("\n");
}


int side_broad(int x)   //创建数字边，方便下棋
{
    printf("%d", x);
    if (x < 10)
        printf("  ");
    else
        printf("  ");
}


int full_broad(char chess[M][N], int L)  //判断是否满棋
{
    int i = 0, j = 0, r = 0;
    for (i = 1; i < L; i++) {
        for (j = 1; j < L; j++) {
            if ('+' == chess[i][j]) {
                return 0;
            }
            else if (chess[i][j] == '1' || chess[i][j] == '0')
                r = r + 1;
        }
    }
    if (r < ((N - 1) * (N - 1)))
        return 0;//棋盘没满
    else
        return 1;//棋盘满了          
}


int setdown(char chess[M][N], int L, int x, int y, char symbol)  //下棋的棋子位置
{
    if ((x < L) && (x > 0) && (y < L) && (y > 0)) {
        if (chess[x][y] == '+') {
            chess[x][y] = symbol;
            return 1;//成功
        }
        else {
            return 0;//失败
        }
    }
    else {
        return 0;//失败
    }
}

int updown_win(char chess[M][N],int x,int y) {
    int i = 0, j = 0, k = 0;
    for (i = 0;  (i < 4) && ((y + i + 1) < N); i++) {
            if (chess[x][y + i] == chess[x][y + i + 1]){
                k = k + 1;
            }
            else break;
    }

    for (i = 0; (chess[x][y + i] != NULL) && (i < 4) && ((y - i - 1) > 0); i++) {
            if (chess[x][y - i] == chess[x][y - i - 1]) {
                k = k + 1;
            }
            else break;
    }
    if (k >= 4)
        return 1;
    else
        return 0;
}

int leftright_win(char chess[M][N], int x, int y) {
    int i = 0, j = 0, k = 0;
    for (i = 0; (i < 4)&& ((x + i + 1) < N ); i++) {
        if (chess[x + i][y] == chess[x + i + 1][y]) {
            k = k + 1;
        }
        else break;
    }

    for (i = 0; (chess[x - i][y] != NULL) && (i < 4) && ((x - i - 1) > 0); i++) {
        if (chess[x - i][y] == chess[x - i - 1][y]) {
            k = k + 1;
        }
        else break;
    }
    if (k >= 4)
        return 1;
    else
        return 0;
}

int xie1_win(char chess[M][N], int x, int y) {
    int i = 0, j = 0, k = 0;
    for (i = 0; (i < 4) && ((x + i + 1) < N ) && ((y + i + 1) < N ); i++) {
        if (chess[x + i][y + i] == chess[x + i + 1][y + i + 1]){
            k = k + 1;
        }
        else break;
    }

    for (i = 0; (chess[x - i][y - i] != NULL) && (i < 4) && ((x - i - 1) > 0) && ((y - i - 1) > 0); i++) {
        if (chess[x - i][y - i] == chess[x - i - 1][y - i - 1]){
            k = k + 1;
        }
        else break;
    }
    if (k >= 4)
        return 1;
    else
        return 0;
}

int xie2_win(char chess[M][N], int x, int y) {
    int i = 0, j = 0, k = 0;
    for (i = 0; (i < 4) && ((x + i + 1) < N) && ((y - i - 1) > 0); i++) {
        if (chess[x + i][y - i] == chess[x + i + 1][y - i - 1]) {
            k = k + 1;
        }
        else break;
    }

    for (i = 0; (i < 4) && ((y + i + 1) < N) && ((x - i - 1) > 0); i++) {
        if (chess[x - i][y + i] == chess[x - i - 1][y + i + 1]) {
            k = k + 1;
        }
        else break;
    }
    if (k >= 4)
        return 1;
    else
        return 0;
}


int judgement(char judge[M][N], int x, int y) {
    int k = 0;
    if ((updown_win(judge, x, y) == 1)) {
        k = k + 1;
    }
    if ((leftright_win(judge, x, y) == 1)) {
        k = k + 1;
    }
    if ((xie1_win(judge, x, y) == 1)) {
        k = k + 1;
    }
    if ((xie2_win(judge, x, y) == 1)) {
        k = k + 1;
    }

    if (k > 0) {
        return 1;
    }
    else return 0;
}

int view_chess(char chess[M][N]) {   //第1次显示棋盘

    int i = 0, j = 0; int L = N;
    for (i = 0; i < L; ++i) {
        if (i < 10) {
            printf("0");
        }
        side_broad(i);
    }
    printf("\n\n");
    fivechess_broad(chess, N);       //打印全部的"+"

    for (i = 1; i < L; i++) {
        if (i < 10) {
            printf("0");
        }
        side_broad(i);               //打印第一列数字
        for (j = 1; j < L; j++) {
            if(chess[i][j]=='+')
            printf("·  ");//输出棋盘
        }
        printf("\n\n");
    }
}

int view2_chess(char chess[M][N]) {   //第N次显示棋盘

    int i = 0, j = 0; int L = N;
    for (i = 0; i < L; ++i) {
        if (i < 10) {
            printf("0");
        }
        side_broad(i);
    }
    printf("\n\n");

    for (i = 1; i < L; i++) {
        if (i < 10) {
            printf("0");
        }
        side_broad(i);
        for (j = 1; j < L; j++) {     //输出棋盘
            if (chess[i][j] == '1') {
                printf("●  ");
            }
            else if (chess[i][j] == '0') {
                printf("○  ");
            }
            else {
                if (chess[i][j] == '+')
                    printf("·  ");
            }
        }
        printf("\n\n");
    }
    line(L);
}


int main() {
    char array[M][N];
    char name_A[100], name_B[100];
    int x = 0, y = 0, m = 1, n = 1; int L = N; 
    int t = 0, z = 0;

    printf("\n五子棋王争霸赛2\n");
    printf("\n玩家A的名字:");
    scanf("%s", name_A);
    printf("\n玩家B的名字:");
    scanf("%s", name_B);            //存入玩家A、玩家B信息
    printf("\n");                    

    view_chess(array);

    while (1)
    {
        if (full_broad(array, N)) {
            printf("\n"); line(L);
            printf("棋盘已满！和局！\n"); line(L);
            break;
        }

        while (1) {
            printf("\n"); line(N);
            printf("请玩家<%s>落子,第<%d>回合,悔棋代码<77-88>\n", name_A, m); line(L);
            printf("输入棋子的横坐标X="); t = x;
            scanf("%d", &x); line(L); z = y;
            printf("输入棋子的列坐标Y=");
            scanf("%d", &y); printf("\n"); line(L);
            getchar();

            if ((x == 77) && (y == 88)) {
                array[t][z] = '+'; n = n - 1; break;
            }
            else {
                if (setdown(array, N, x, y, '1')) {
                    m = m + 1;
                    break;
                }
                else {
                    printf("\n"); line(N);
                    printf("落子失败，请重新选定合适位置\n"); line(N);
                    continue;
                }
            }
        }
        view2_chess(array);
        if (judgement(array, x, y)) {
            printf("\n恭喜玩家<%s>在第<%d>回合取得胜利！(⊙v⊙)\n", name_A,m-1); line(N);
            break;
        }


        while (1) {
            printf("\n"); line(N);
            printf("请玩家<%s>落子,第<%d>回合,悔棋代码<77-88>\n", name_B, n); line(L);
            printf("输入棋子的横坐标X="); t = x;
            scanf("%d", &x); line(L);
            printf("输入棋子的列坐标Y="); z = y;
            scanf("%d", &y); printf("\n");line(L);
            getchar();

            if ((x == 77) && (y == 88)) {
                array[t][z] = '+'; m = m - 1; break;
            }
            else {
                if (setdown(array, N, x, y, '0')) {
                    n = n + 1;
                    break;
                }
                else {
                    printf("落子失败，请重新选定位置");
                    continue;
                }
            }
        }
        view2_chess(array);
        if (judgement(array, x, y)) {
            printf("\n恭喜玩家<%s>在第<%d>回合取得胜利！(⊙v⊙)\n", name_B, n-1); line(N);
            break;
        }
    }
}

